package com.yk.framework.gui.ctrl;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

/**
 * @author lifetime
 * 
 */
public class YKTable extends JTable {
	private YKScrollPane scrollPane;
	private JTable rowHeader;
	protected DefaultTableModel ykTableModel;

	public YKTable() {
		super();

		init();
	}

	/**
	 * @param columnNames
	 */
	public YKTable(Object[] columnNames) {
		super();
		ykTableModel = (DefaultTableModel) this.getModel();
		for (int i = 0; i < columnNames.length; i++) {
			ykTableModel.addColumn(columnNames[i]);
		}
		init();
	}

	protected void init() {
		ykTableModel = (DefaultTableModel) this.getModel();
		if (ykTableModel == null) {
			ykTableModel = new DefaultTableModel();
		}
		scrollPane = new YKScrollPane(this);
		rowHeader = new JTable(new DefaultTableModel() {

			public int getColumnCount() {
				return 1;
			}

			public String getColumnName(int i) {
				return "indexColumn";
			}

			public int getRowCount() {
				return ykTableModel.getRowCount();
			}

			public Object getValueAt(int i, int j) {
				return i + 1;
			}

			public boolean isCellEditable(int i, int j) {
				return false;
			}

		});
		rowHeader.setDragEnabled(false);
		TableColumn column = rowHeader.getColumn("indexColumn");
		column.setWidth(30);
		column.setCellRenderer(new RowIndexRenderer());
		rowHeader.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		rowHeader.setPreferredScrollableViewportSize(new Dimension(30, 0));
		rowHeader.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				if (e.getValueIsAdjusting()) {
					int indexs[] = rowHeader.getSelectedRows();
					if (indexs.length > 1) {
						YKTable.this.getSelectionModel().addSelectionInterval(indexs[0], indexs[indexs.length - 1]);
					} else if (indexs.length == 1) {
						YKTable.this.getSelectionModel().addSelectionInterval(indexs[0], indexs[0]);
					}
				}
			}
		});
		rowHeader.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				Point p = e.getPoint();
				int row = rowHeader.rowAtPoint(p);
				if (row >= 0) {
					rowHeader.clearSelection();
					YKTable.this.clearSelection();
					rowHeader.getSelectionModel().addSelectionInterval(row, row);
					YKTable.this.repaint();
				}
			}
		});
		scrollPane.setRowHeaderView(rowHeader);
		this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
	}

	private class RowIndexRenderer extends JLabel implements TableCellRenderer {
		Color selectColor = new Color(157, 193, 228);
		Color bg = new Color(179, 212, 216);

		public RowIndexRenderer() {
			setOpaque(true);
			setHorizontalAlignment(JLabel.LEFT);
			YKTable.this.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
				public void valueChanged(ListSelectionEvent e) {
					rowHeader.clearSelection();
					rowHeader.repaint();
				}
			});
		}

		public Component getTableCellRendererComponent(JTable jtable, Object obj, boolean isSelected, boolean hasFocus, final int row, int j) {
			if (isSelected) {
				setBackground(selectColor);
			} else {
				setBackground(bg);
				int[] indexs = YKTable.this.getSelectedRows();
				for (int k = 0; k < indexs.length; k++) {
					if (row == indexs[k]) {
						setBackground(selectColor);
					}
				}
			}
			setText(String.valueOf(obj));
			return this;
		}

		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			Graphics2D g2 = (Graphics2D) g.create();
			GradientPaint paint = new GradientPaint(0, 0, Color.white, getWidth(), getHeight(), Color.blue);
			g2.setPaint(paint);
			g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
			g2.fillRoundRect(0, 0, getWidth(), getHeight(), 8, 8);
			g2.dispose();
		}
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		Vector<Vector<String>> vector = new Vector<Vector<String>>();
		for (int i = 0; i < 30000; i++) {
			Vector<String> v1 = new Vector<String>();
			v1.add("a" + i);
			v1.add("b" + i);
			vector.add(v1);
		}
		Vector<String> vector2 = new Vector<String>();
		vector2.add("aaa");
		vector2.add("bbb");
		YKTable table = new YKTable(vector, vector2);
		frame.getContentPane().add(table.getScrollPane());
		frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}

	public YKTable(int i, int j) {
		super(i, j);
		init();
	}

	public YKTable(TableModel tablemodel, TableColumnModel tablecolumnmodel, ListSelectionModel listselectionmodel) {
		super(tablemodel, tablecolumnmodel, listselectionmodel);
		init();
	}

	public YKTable(TableModel tablemodel, TableColumnModel tablecolumnmodel) {
		super(tablemodel, tablecolumnmodel);
		init();
	}

	public YKTable(TableModel tablemodel) {
		super(tablemodel);
		init();
	}

	public YKTable(Vector vector, Vector vector1) {
		super(vector, vector1);
		init();
	}

	public YKScrollPane getScrollPane() {
		return scrollPane;
	}

	public void setScrollPane(YKScrollPane scrollPane) {
		this.scrollPane = scrollPane;
	}

	public JTable getRowHeader() {
		return rowHeader;
	}

	public void setRowHeader(JTable rowHeader) {
		this.rowHeader = rowHeader;
	}

	public DefaultTableModel getYkTableModel() {
		return ykTableModel;
	}

	public void setYkTableModel(DefaultTableModel ykTableModel) {
		this.ykTableModel = ykTableModel;
		setModel(ykTableModel);
	}

}
